package ae.pcfc.etks.online.web.controller.user.general.finance;

/* $Id: UserPersonController 
 * Copyright (C) 2011, Trakhees
 *  
 *  History
 *
 * Date  			Author 					Remarks
 * -------------------------------------------------------------
 * April 13, 2011 	Neha_Chauhan 	        Created
 *
 */

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ConnectException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.UnhandledException;
import org.joda.time.DateTime;
import org.joda.time.Days;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.support.SessionStatus;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.support.RequestContextUtils;

import ae.pcfc.etks.online.common.delegate.ClientRegistrationDelegate;
import ae.pcfc.etks.online.common.vo.LabelVO;
import ae.pcfc.etks.online.fnp.exception.FNPException;
import ae.pcfc.etks.online.fnp.service.FNPService;
import ae.pcfc.etks.online.web.ConstantsAdmin;
import ae.pcfc.etks.online.web.PageType;
import ae.pcfc.etks.online.web.ViewPath;
import ae.pcfc.etks.online.web.ViewUtils;
import ae.pcfc.etks.online.web.controller.BaseController;
import ae.pcfc.etks.online.web.controller.user.general.person.UserPersonController;
import ae.pcfc.etks.online.web.model.ClientPrepaidAccount;

/**
 * Controller that handles all {@link UserPersonController}-related requests,
 * i.e.: all requests for /user/general/finance/prepaid
 * 
 * @author Neha Chauhan
 */

@Controller
@RequestMapping(ViewPath.FINANCE_PREPAID_SERVICE)
public class PrePaidServiceController extends BaseController {

	private static Logger log = LoggerFactory
			.getLogger(PrePaidServiceController.class);

	private FNPService fnpDelegate;

	@Resource(name = "fnpDelegate")
	public void setFnpDelegate(FNPService fnpDelegate) {
		this.fnpDelegate = fnpDelegate;
	}

	private ClientRegistrationDelegate clientRegistrationDelegate;

	@Resource(name = "clientRegistrationDelegate")
	public void setClientRegistrationDelegate(
			ClientRegistrationDelegate clientRegistrationDelegate) {
		this.clientRegistrationDelegate = clientRegistrationDelegate;
	}
	
	private Map<String, String> propertyConstants;

	@Resource(name = "propertyConstants")
	public void setPropertyConstants(Map<String, String> propertyConstants) {
		this.propertyConstants = propertyConstants;
	}
	
	/**
	 * Custom handler for displaying the form, i.e.: GET requests for
	 * /user/general/finance/prepaid Note that this handler returns void instead
	 * of a {@link ModelAndView}, signifying a default logical view name should
	 * be selected by Spring MVC. The ui {@link Model} is supplied as a
	 * parameter to the method and populated with the new model object to be
	 * rendered.
	 * 
	 * 
	 * @see WEB-INF/jsp/user/general/finance/prepaid/show.jsp
	 */
	@RequestMapping(value = "/show.htm", method = RequestMethod.GET)
	public void show(
			@ModelAttribute(value = ConstantsAdmin.CLIENT_PREPAID_ACCOUNT_MODEL_KEY) ClientPrepaidAccount clientPrepaidAccount,
			Model map) {

		// return ViewUtils.getRedirect(ViewPath.USER_SERVICE, PageType.SHOW);

	}

	@ModelAttribute(ConstantsAdmin.EXPORT_OPTION_MODEL_KEY)
	public List<LabelVO> populateExportOption(Locale locale) {

		List<LabelVO> labelList = new ArrayList<LabelVO>();
		LabelVO labelVO = new LabelVO();
		labelVO.setId("PDF");
		
		labelVO.setLabelAr(getMessageSource().getMessage("export.option.pdf", null,locale));
		labelVO.setLabelEn(getMessageSource().getMessage("export.option.pdf", null,locale));

		labelList.add(labelVO);

		labelVO = new LabelVO();
		labelVO.setId("XLSX");
		
		labelVO.setLabelAr(getMessageSource().getMessage("export.option.excel", null,locale));
		labelVO.setLabelEn(getMessageSource().getMessage("export.option.excel", null,locale));

		labelList.add(labelVO);

		return labelList;
	}

	@RequestMapping(method = RequestMethod.POST, value = "/show.htm")
	public String show(
			HttpServletRequest request,
			HttpServletResponse response,
			SessionStatus status,
			HttpSession session,
			Model model,
			@ModelAttribute(value = ConstantsAdmin.CLIENT_PREPAID_ACCOUNT_MODEL_KEY) ClientPrepaidAccount clientPrepaidAccount,
			BindingResult errors) {

		try {

			if (errors.hasErrors()) {
				return ViewUtils.getForward(ViewPath.FINANCE_PREPAID_SERVICE,
						PageType.SHOW);
			}

			// Check if the selected period is less than or equal to 100 days
			int days = Days.daysBetween(
					new DateTime(clientPrepaidAccount.getStartDate()),
					new DateTime(clientPrepaidAccount.getEndDate())).getDays();
			if (days >= 100) {

				String[] messageArgs2 = new String[] { getMessageSource()
						.getMessage("error.finance.maxDateRange100", null,
								RequestContextUtils.getLocale(request)) };
				errors.reject("error.finance.maxDateRange100", messageArgs2,
						null);

				return ViewUtils.getForward(ViewPath.FINANCE_PREPAID_SERVICE,
						PageType.SHOW);

			}

			Object principal = SecurityContextHolder.getContext()
					.getAuthentication().getPrincipal();
			String strUserName = null;

			if (principal instanceof UserDetails) {
				strUserName = ((UserDetails) principal).getUsername();
			} else {
				strUserName = principal.toString();
			}

			String trakheesId = null;
			if (strUserName != null)
				trakheesId = this.clientRegistrationDelegate
						.findTrakheesIdByUserName(strUserName);

			if (trakheesId == null || trakheesId.isEmpty()) {

				String[] messageArgs = new String[] { getMessageSource()
						.getMessage("error.client.detail.not.found", null,
								RequestContextUtils.getLocale(request)) };
				log.debug("Trakhees Id not found agains the user");
				errors.reject("error.client.detail.not.found", messageArgs,
						null);

				return ViewUtils.getForward(ViewPath.FINANCE_PREPAID_SERVICE,
						PageType.SHOW);

			}

			Byte[] bytes = this.fnpDelegate.getClientPrepaidAccountReport(
					clientPrepaidAccount.getStartDate(),
					clientPrepaidAccount.getEndDate(), trakheesId,
					ConstantsAdmin.SYSTEM_NAME_ONLINE_ADMIN,
					clientPrepaidAccount.getExportOption());

			String tempFileName = "" + System.currentTimeMillis()+"."+clientPrepaidAccount.getExportOption().toLowerCase();
			//String fileExtension = clientPrepaidAccount.getExportOption().toLowerCase();
			String tempFolderPath = propertyConstants.get(ConstantsAdmin.TEMP_UPLOAD_FILES_PATH_KEY);
			
			File uploadedFile = new File(tempFolderPath + tempFileName);
			FileOutputStream fos = new FileOutputStream(uploadedFile);
			// strFinalVersion =
			// StringUtils.trimAllWhitespace(mpf.getOriginalFilename());
			fos.write(ArrayUtils.toPrimitive(bytes));
			fos.close();
			response.reset();	
			response.setContentType("application/"+clientPrepaidAccount.getExportOption().toLowerCase());
			response.getOutputStream().write(ArrayUtils.toPrimitive(bytes));
			response.setHeader("Content-Disposition","attachment;filename=PrepaidAccountReport."+clientPrepaidAccount.getExportOption().toLowerCase());
			response.flushBuffer();

			//Map<String, String> paramMap = new HashMap<String, String>();

			//paramMap.put("tempFileName", tempFileName);

			
			//return ViewUtils.getRedirect(ViewPath.FILE, PageType.TEMPFILE, paramMap);

			 return ViewUtils.DEFAULT_VIEW;

		} catch (ConnectException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.internal.error.occurred", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (FNPException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.internal.error.occurred.with.args", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			String[] messageArgs = new String[] { e.getMessage() };
			errors.reject("error.internal.error.occurred", messageArgs, null);
			log.error(e.getMessage());
			e.printStackTrace();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage());
			throw new UnhandledException(e.getMessage(), e.getCause());
		}

		return ViewUtils.getForward(ViewPath.FINANCE_PREPAID_SERVICE,
				PageType.SHOW);
	}

}
